package sh.orm.util;

import com.mysql.jdbc.JDBC4Connection;
import sh.orm.OrmException;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 自己写的一个简单的数据库连接池
 * //使用队列，创建连接，或者服务使用完之后返回连接是入队列， 获取连接是出队列
 * @author lqq
 * @date 2019/1/19
 */
public class ConnectionPool {


    /**
     * 使用普通队列导致服务拿到的空指针连接，所以使用阻塞队列
     */
    //static final Queue<Connection> connectionQueue = new LinkedBlockingDeque<Connection>(3);
    static final BlockingQueue<Connection> connectionQueue = new LinkedBlockingDeque<Connection>(3);

    static volatile ConnectionPool singleton  ;

    /**
     * 在连接池中返回一个现有连接,<br></>
     * <b> 当没有连接时进行阻塞，而不是返回空值<b/>
     *
     * @return
     */
    public Connection getConnection(){
        try {
            return connectionQueue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
            throw new OrmException("获取数据库连接异常" + e.getMessage());
        }
        //return connectionQueue.poll();
    }


    /**
     * 私有构造方法，不能new对象
     */
    private ConnectionPool(){}

    /**
     * 返回单例的对象
     * @return
     */
    public static ConnectionPool getInstance(){
        if(singleton != null){
        }else{
            synchronized (ConnectionPool.class){
                // 这里进行双重检查， https://www.cnblogs.com/xz816111/p/8470048.html
                // volatile 防止指令重排序(分配内存、初始化对象、指向对象)，双重检查是为了多个线程同时通过第一个检查，加锁之后再检查
                if(singleton == null){
                    singleton = new ConnectionPool();
                    //初始化
                    singleton.init();
                }
            }
        }
        return singleton;
    }


    /**
     * 初始化，创建多个数据库连接
     */
    private void init(){
        try {
            //加载驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/shenhang?useUnicode=true&characterEncoding=UTF8";
            Connection conn = null;
            for(int i = 0 ; i < 3 ; i++){
                conn = DriverManager.getConnection(url, "root", "root");
                ((JDBC4Connection)conn).setConnectionQueue(connectionQueue);
                connectionQueue.add(conn);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{


        }
    }

}
